package defectsim.resources;

import javax.vecmath.Vector2d;

import repast.simphony.space.continuous.NdPoint;

import defectsim.Globals;
import defectsim.Util;

/**
 * InteractionStress computes the interaction stress between two edge dislocations
 * 
 * @author Altu� Uzunali
 *
 */
public class InteractionStress {
	
	/**
	 * Computes interaction stress vector in polar coordinates between two parallel edge dislocations 
	 * lying on the same or different slip planes with different slip directions.  
	 * 
	 * @param pointI is the location of the dislocation I on continuous space
	 * @param pointJ is the location of the dislocation J on continuous space
	 * @param directionI is the direction of dislocation I on the slip plane 
	 * @param directionJ is the direction of dislocation J on the slip plane
	 * @param burgersVectorJ is the Burgers vector of the dislocation J
	 * @param A is the material dependent value in the formula
	 * @param minPerceptionRadius is the minimum perception radius
	 * @param maxPerceptionRadius is the maximum perception radius
	 * @param boxLength is the length of the simulation box
	 * @return stress vector with glide and climb components
	 */
	public static Vector2d compute(NdPoint pointI, NdPoint pointJ, double directionI, double directionJ,
			double burgersVectorJ, double A, double minPerceptionRadius, double maxPerceptionRadius, 
			double boxLength){
		double distance = Util.calculateMICDistance(pointI, pointJ, boxLength);
		double angle = Util.calculateMICAngle(pointI, pointJ, boxLength);
		if (distance > 0 && distance <= maxPerceptionRadius)
		// In order to avoid the singularity at the core of dislocation, distance is not allowed 
		// to be little than minimum perception radius
			if (distance < minPerceptionRadius)
				distance = minPerceptionRadius;
		
		// Switching function is used to reduce the effect of cutoff mechanism 
		// close to maximum perception radius
		double distance2 = distance * distance;
		double maxPerceptionRadius2 = maxPerceptionRadius * maxPerceptionRadius;
		double switchFactor = 1 - (distance2 / maxPerceptionRadius2);
		switchFactor = switchFactor * switchFactor;

		double teta = angle - Math.toRadians(directionI);
		double gamma = angle - Math.toRadians(directionJ);
		
		double glideStress = -A * burgersVectorJ * Math.cos(teta) * Math.cos(2 * gamma) / (distance * Globals.MICROMETER_TO_NANOMETER);
		double climbStress = -A * burgersVectorJ * (Math.sin(teta) + Math.sin(gamma) * Math.cos(teta)) / (distance * Globals.MICROMETER_TO_NANOMETER); 

		return new Vector2d(switchFactor * glideStress, switchFactor * climbStress);
	}
	
	public static Vector2d compute(){
		
		return null;
	}
}
